package com.ruoyi.web.controller.outpatient;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.ContentType;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.ruoyi.common.constant.PersonConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.OSSEntity;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.https.HttpUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.outpatient.core.LoginPatient;
import com.ruoyi.outpatient.core.SecurityUtils;
import com.ruoyi.outpatient.domain.PatientIdentity;
import com.ruoyi.outpatient.domain.Person;
import com.ruoyi.outpatient.mapper.IPersonLoginMapper;
import com.ruoyi.outpatient.mapper.patient.PatientRegMapper;
import com.ruoyi.outpatient.service.IPersonLoginService;
import com.ruoyi.outpatient.service.IPersonService;
import com.ruoyi.outpatient.service.impl.PersonLoginServiceImpl;
import com.ruoyi.outpatient.service.patient.IPatientRegService;
import com.ruoyi.outpatient.service.patient.impl.PatientTokenService;
import org.apache.http.HttpResponse;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * Demo class
 *
 * @author 伟峰
 * @date 2022/4/16
 */
@RestController
@RequestMapping("/person")
public class PersonLoginController extends BaseController {


    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IPersonLoginService personLoginService;

    @Autowired
    private IPersonLoginMapper personLoginMapper;


    @Autowired
    private IPersonService personService;


    @Autowired
    private SecurityUtils securityUtils;


    /**
     * 获取手机验证码
     *
     * @param phonenumber 手机号
     * @return 验证码
     */
    @GetMapping("/verification")
    public AjaxResult verification(
            @NotBlank(message = "手机号码不能为空")
            @Size(min = 11, max = 11, message = "手机号码不正确")
            @RequestParam("phonenumber") String phonenumber) {


       AjaxResult result= personService.selectVerification(phonenumber);

        return result;

    }


    /**
     * 验证码登录
     *
     * @param phonenumber 手机号
     * @param verify      验证码
     * @return token
     */
    @PostMapping("/login/verify")
    public AjaxResult patientLogin(
            @NotBlank(message = "手机号不能为空")
            @Size(min = 11, max = 11, message = "手机号码不正确")
            @RequestParam("phonenumber") String phonenumber,

            @NotBlank(message = "验证码不能为空")
            @Size(min = 6, max = 6, message = "验证码格式不正确")
            @RequestParam("verify") String verify
    ) {


//        1.判断验证码是否正确
        String code = redisCache.getCacheObject(PersonConstants.LOGIN_PHONE + phonenumber);
        if (!verify.equals(code)) {
            return AjaxResult.error("验证码错误");
        }
//        2.判断验证码有效期(需要不超过一分钟)
        Long verifyIndate = redisCache.getCacheObject(PersonConstants.LOGIN_VERIFY + verify);
//        如果当前时间-有效时间>60 秒=60000 毫秒则过期
        if (System.currentTimeMillis()-verifyIndate>PersonConstants.VERIFY_INDATE){
            return AjaxResult.error("验证码已过期");
        }



//        3.如果都正确,则生成token返回
        String token = personLoginService.verifyLogin(phonenumber);

        if (StringUtils.isNotNull(token)) {
            return AjaxResult.success("登录成功").put("token", token);
        }
        return AjaxResult.error("该账户不存在");

    }


    //    手机密码登录
    @PostMapping("/login/password")
    public AjaxResult patientLogin(
            @NotBlank(message = "手机号不能为空")
            @Size(min = 11, max = 11, message = "手机号码不正确")
            @RequestParam("phonenumber") String phonenumber,

            @NotBlank(message = "密码不能为空")
            @RequestParam("password") String password,
            HttpServletRequest request) {

        // TODO: 2022/5/15 后期必须优化 双过滤器链 
        StringBuffer buffer = new StringBuffer();

        buffer.append(request.getHeader("person"));
        buffer.append("_");
        buffer.append(phonenumber);


        String token = personLoginService.passwordLogin(buffer.toString(), password);

        if (StringUtils.isNotNull(token)) {
            return AjaxResult.success("登录成功").put("token", token);
        }
        return AjaxResult.error("该用户不存在");

    }




//    登录退出  直接在过滤器链中,不需要
    @GetMapping("/loginoutaa")
    public AjaxResult myInformation()
    {
        return null;
    }



    /**
     * 通过personid查询个人资料
     * @param personId
     * @return person
     */
    @GetMapping("/information")
    public AjaxResult myInformation(
            @NotNull(message = "id不能为空")
            @RequestParam(value = "personId",required = false)Long personId)
    {  //其他
        if (personId==null){
            Long loginPersonId = securityUtils.getLoginPersonId();
            AjaxResult person=personService.selectMyInformation(loginPersonId);
            return person;
        }else {
            AjaxResult person=personService.selectMyInformation(personId);
            return person;
        }

    }

    /**
     *通过personId查询个人分享文章
     * @param id
     * @return
     */
    @GetMapping("/myblog")
    public AjaxResult myBlogList(
            @NotNull(message = "id不能为空")
        @RequestParam(value = "personId",required = false)Long personId)
        {  //其他
            if (personId==null){
                Long loginPersonId = securityUtils.getLoginPersonId();
                AjaxResult person=personService.selectMyBlogList(loginPersonId);
                return person;
            }else {
                AjaxResult person=personService.selectMyBlogList(personId);
                return person;
            }



//        Long loginPersonId = securityUtils.getLoginPersonId();

    }


    /**
     *通过personId查询个人收藏文章
     * @return
     */
    @GetMapping("/mycollect")
    public AjaxResult myCollectList(
            @RequestParam("id")Long id
    )
    {


//        Long loginPersonId = securityUtils.getLoginPersonId();

        AjaxResult person=personService.selectMyCollectList(id);
        return person;
    }



    /**
     * 个人信息更改
     * @param person
     * @return
     */
    @PostMapping("/update")
    public AjaxResult informationUpdate(
           @Validated @RequestBody Person person)
    {
       return personService.informationUpdate(person);

    }



    @Autowired
    private OSSEntity ossEntity;
    @Value("${url.images}")
    private String URLHeader;
    /**
     * 上传头像并返回头像URL
     * @param avatar
     * @return
     */
    @PostMapping("/avatar")
    public AjaxResult avatarUpdate(
            @NotBlank(message = "头像不能为空") MultipartFile avatar,
            HttpServletRequest request)
    {


        String endpoint = ossEntity.getEndpoint();
        String accessKeyId = ossEntity.getAccessKeyId();
        String accessKeySecret = ossEntity.getAccessKeySecret();
        String bucketName = ossEntity.getBucketName();


        String contentType1 = avatar.getContentType();
        String contentType = request.getContentType();


        System.out.println(contentType);
        StringBuffer buffer=new StringBuffer();
        buffer.append(URLHeader);

//             创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            try {
//                1.将上传的图片转为输入流 用于存入OSSClient实例
                InputStream inputStream1 = avatar.getInputStream();

                String date = DateUtils.getDate();
//                2.设置文件名     yyyy-mm-dd/ +  获取的是图片的完整名称
                String fileName = date + "/" + UUID.randomUUID() + avatar.getOriginalFilename();
                buffer.append(fileName);
                // 创建PutObject请求。
                ossClient.putObject(bucketName, fileName, inputStream1);
            } catch (OSSException oe) {
                System.out.println("Caught an OSSException, which means your request made it to OSS, "
                        + "but was rejected with an error response for some reason.");
                System.out.println("Error Message:" + oe.getErrorMessage());
                System.out.println("Error Code:" + oe.getErrorCode());
                System.out.println("Request ID:" + oe.getRequestId());
                System.out.println("Host ID:" + oe.getHostId());
            } catch (ClientException ce) {
                System.out.println("Caught an ClientException, which means the client encountered "
                        + "a serious internal problem while trying to communicate with OSS, "
                        + "such as not being able to access the network.");
                System.out.println("Error Message:" + ce.getMessage());
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (ossClient != null) {
                    ossClient.shutdown(); //关闭流
                    System.out.println("上传完成");
                }
            }

        String avatarName=buffer.toString();
        return AjaxResult.success().put("avatarName",avatarName);

    }



    /**
     * 签到功能
     * @return
     */
    @PostMapping("/sign")
    public AjaxResult personalSign()
    {
        return personService.insertSign();
    }


    /**
     * 对我blog进行点赞和收藏的人
     * @return
     */
    @GetMapping("/likeAndCollect")
    public AjaxResult likeAndCollect()
    {
        return personService.selectLikeAndCollect();
    }






}
